package com.sky.d_fork_jion;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * Callable与 Future
 * @Author:hjt
 */
public class CallableAndFuture {

	public static class MyCallable implements Callable<String> {

		private int flag = 0;
		
		public MyCallable(int flag){
			this.flag = flag;
		}
		
		@Override
		public String call() throws Exception {
			
			if(this.flag == 0){
				return "flag = 0";
			}
			
			if (this.flag == 1){
				try {
					while(true){
						System.out.println("looping.");
						Thread.sleep(2000);
					}
				} catch (InterruptedException e) {
					System.out.println("Interrupted");
				}
				return "false";
			} else {
				throw new Exception("Bad flag value");
			}
		}
		
	}
	
	public static void main(String[] args) {
		//定义三个任务
		MyCallable t1 = new MyCallable(0);
		MyCallable t2 = new MyCallable(1);
		MyCallable t3 = new MyCallable(2);
		
		//创建执行服务
		ExecutorService executorService = Executors.newFixedThreadPool(3);
		
		
		try {
			//提交并执行任务
			Future<String> f1 = executorService.submit(t1);
			//如果调用get方法，当前线程会等待任务执行完毕之后才往下执行
			System.out.println("task1:" + f1.get());
			
			Future<String> f2 = executorService.submit(t2);
			//等待5秒  t2是无限循环的任务
			Thread.sleep(5000);
			System.out.println("task2 cancel:" + f2.cancel(true));
			
			//获取第三个任务会抛异常，捕获查看
			Future<String> f3 = executorService.submit(t3);
			System.out.println("task3:" + f3.get());
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (ExecutionException e) {
			e.printStackTrace();
		 }
		
		//执行结束停止任务
		executorService.shutdown();
	}
}

/**
 	Callable和Runnable的区别：
		Callable定义的方法是call，而Runnable定义的方法是run。
		Callable的call方法可以有返回值，而Runnable的run方法不能有返回值。
		Callable的call方法可抛出异常，而Runnable的run方法不能抛出异常
	
	Future表示异步计算的结果，它提供了检查计算是否完成的方法，以等待计算的完成，并检索计算的结果。
	Future的cancel方法可以取消任务的执行，它有一布尔参数，参数为 true 表示立即中断任务的执行，
	参数为 false 表示允许正在运行的任务运行完成。
	Future的 get 方法等待计算完成，获取计算结果
 */
